package com.ymt.bpm.dao;

import com.mongodb.WriteResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;

@Repository
public class MongoDao {

    /**
     * spring mongodb 集成操作类
     */
    @Autowired
    protected MongoTemplate mongoTemplate;

    /**
     * 注入mongodbTemplate
     * @param mongoTemplate
     */
    protected void setMongoTemplate(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public <T> T save(String collectionName, T entity) {
        mongoTemplate.save(entity, collectionName);
        return entity;
    }

    public <T> T findById(String collectionName, String id, Class<T> entityClass) {
        return mongoTemplate.findById(id, entityClass, collectionName);
    }

    public <T> List<T> findAll(String collectionName, Class<T> entityClass) {
        return mongoTemplate.findAll(entityClass, collectionName);
    }

    public <T> List<T> find(String collectionName, Query query, Class<T> entityClass) {
        return mongoTemplate.find(query, entityClass, collectionName);
    }

    public <T> T findOne(String collectionName, Query query, Class<T> entityClass) {
        return mongoTemplate.findOne(query, entityClass, collectionName);
    }

    public <T> List<T> findPage(String collectionName, Query query, Class<T> entityClass, int fromRow, int toRow, List<Sort> sorts) {
        query.skip(fromRow-1).limit(toRow - fromRow + 1);
        if (sorts!=null && sorts.size()>0) {
            for (Sort sort : sorts) {
                query.with(sort);
            }
        }
        List<T> rows = this.find(collectionName, query, entityClass);
        return rows;
    }

    public <T> long count(String collectionName, Query query, Class<T> entityClass) {
        return mongoTemplate.count(query, entityClass, collectionName);
    }

    public <T> WriteResult update(String collectionName, Query query, Update update, Class<T> entityClass) {
        if (update==null) {
            return null;
        }
        return mongoTemplate.updateMulti(query, update, entityClass, collectionName);
    }

    public <T> T updateOne(String collectionName, Query query, Update update, Class<T> entityClass) {
        if (update==null) {
            return null;
        }
        return mongoTemplate.findAndModify(query, update, entityClass, collectionName);
    }

    public <T> int delete(String collectionName, Query query, Class<T> entityClass) {
        WriteResult wr = mongoTemplate.remove(query, entityClass, collectionName);
        return wr.getN();
    }

    public void batchInert(String collectionName, Collection<? extends Object> batchToSave) {
        mongoTemplate.insert(batchToSave, collectionName);
    }

    /*public <T> WriteResult update(T entity) {
        Field[] fields = this.getEntityClass().getDeclaredFields();
        if (fields == null || fields.length <= 0) {
            return null;
        }
        Field idField = null;
        // 查找ID的field
        for (Field field : fields) {
            if (field.getName() != null
                    && "id".equals(field.getName().toLowerCase())) {
                idField = field;
                break;
            }
        }
        if (idField == null) {
            return null;
        }
        idField.setAccessible(true);
        String id=null;
        try {
            id = (String) idField.get(entity);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        if (id == null || "".equals(id.trim()))
            return null;
        // 根据ID更新
        Query query = new Query(Criteria.where("_id").is(id));
        // 更新
        // Update update = new Update();
        // for (Field field : fields) {
        // // 不为空 不是主键 不是序列化号
        // if (field != null
        // && field != idField
        // && !"serialversionuid"
        // .equals(field.getName().toLowerCase())) {
        // field.setAccessible(true);
        // Object obj = field.get(entity);
        // if (obj == null)
        // continue;
        // update.set(field.getName(), obj);
        // }
        // }
        Update update = ReflectionUtils.getUpdateObj(entity);
        if (update == null) {
            return null;
        }
        return mongoTemplate.updateFirst(query, update, getEntityClass());
    }*/

}
